package fr.resasante.ejb.service.helper;

import javax.naming.NamingException;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.jboss.logging.Logger;

import fr.resasante.ejb.dto.User;
import fr.resasante.ejb.util.HibernateUtil;
import fr.resasante.ejb.utils.EjbResponse;
import fr.resasante.utils.CommonUtils;
import fr.resasante.utils.DepartmentsUtils;

/**
 * Class for getting system properties
 * 
 * @author GEFFROY-DE-VILLEBLAN
 * 
 */
public final class UserUpdateHelper {
	/**
	 * EJb response
	 */
	private EjbResponse ejbResponse = null;

	/**
	 * class instance
	 */
	private static volatile UserUpdateHelper instance = null;

	/**
	 * Logger for the class
	 */
	private static final Logger logger = Logger.getLogger(UserUpdateHelper.class.getName());

	/**
	 * Method returning a Singleton class instance
	 * 
	 * @return Singleton instance
	 * @throws NamingException
	 */
	public final static UserUpdateHelper getInstance() {
		if (UserUpdateHelper.instance == null) {
			synchronized (UserUpdateHelper.class) {
				if (UserUpdateHelper.instance == null) {
					UserUpdateHelper.instance = new UserUpdateHelper();
				}
			}
		}
		return UserUpdateHelper.instance;
	}

	/**
	 * Constructor
	 */
	private UserUpdateHelper() {
		super();
	}

	/**
	 * Changes the address for an user
	 * 
	 * @param user
	 *            The user
	 * @return If the change is successful
	 */
	public boolean changeAddress(User user) {
		int result = 0;
		final Session session = HibernateUtil.getSession();
		ejbResponse = new EjbResponse();
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			final Query query = session.createQuery("update User "
					+ "set postalAddress = :postalAddress, " + "postalCode = :postalCode, "
					+ "postOfficeBox = :postOfficeBox, " + "city = :city, "
					+ "departmentLabel = :departmentLabel, "
					+ "departmentCode = :departmentCode " + "where user_id = :user_id");
			query.setParameter("postalAddress", user.getPostalAddress());
			query.setParameter("postalCode", user.getPostalCode());
			query.setParameter("postOfficeBox", user.getPostOfficeBox());
			query.setParameter("city", user.getCity());
			query.setParameter("departmentCode", user.getDepartmentCode());
			query.setParameter("departmentLabel", DepartmentsUtils.getInstance()
					.getLabelDepartementByCode(user.getDepartmentCode()));
			query.setParameter("user_id", user.getUserId());
			result = query.executeUpdate();
			transaction.commit();
		} catch (final RuntimeException e) {
			logger.error(CommonUtils.getInstance().getStackTrace(e));
			if (transaction != null) {
				transaction.rollback();
			}
			ejbResponse.addError("error.from.database");
		} finally {
			session.close();
		}
		if (result == 1) {
			return true;
		}
		return false;
	}

	/**
	 * Changes the password for an user
	 * 
	 * @param userIncoming
	 *            the user object
	 * @return
	 */
	public boolean changePassword(User user) {
		int result = 0;
		final Session session = HibernateUtil.getSession();
		ejbResponse = new EjbResponse();
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			final Query query = session.createQuery("update User "
					+ "set password = :password, salt = :salt where user_id = :user_id");
			query.setParameter("password",
					CommonUtils.getInstance().encryptPassword(user.getPassword()));
			query.setParameter("salt", CommonUtils.getInstance().generateSalt());
			query.setParameter("user_id", user.getUserId());
			result = query.executeUpdate();
			transaction.commit();
		} catch (final RuntimeException e) {
			logger.error(CommonUtils.getInstance().getStackTrace(e));
			if (transaction != null) {
				transaction.rollback();
			}
			ejbResponse.addError("error.from.database");
		} finally {
			session.close();
		}
		if (result == 1) {
			return true;
		}
		return false;
	}

	/**
	 * Enable an user
	 * 
	 * @param salt
	 *            The salt
	 * @return The EJB response
	 */
	public EjbResponse confirmUser(String salt) {
		final EjbResponse ejbResponse = new EjbResponse();
		final User user = UserViewHelper.getInstance().getUserBySalt(salt, false);
		if (null != user) {
			final Session session = HibernateUtil.getSession();
			Transaction transaction = null;
			try {
				transaction = session.beginTransaction();
				user.setEnabled(true);
				session.update(user);
				transaction.commit();
				logger.info(user.getUsername() + " successfully confirmed !");
			} catch (final RuntimeException e) {
				logger.error(CommonUtils.getInstance().getStackTrace(e));
				if (transaction != null) {
					transaction.rollback();
				}
				ejbResponse.addError("error.from.database");
			} finally {
				session.close();
			}
		} else {
			ejbResponse.addError("error.salt.unknown");
		}
		return ejbResponse;
	}
}